﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Data;
using System.Windows.Media;


namespace Finance.UI.Utils
{
    public class CashPercentColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (typeof(double).IsAssignableFrom(value.GetType()))
            {
                var percent = (double)value;
                //if (percent > 1 || percent < 0)
                //{
                //    //throw new ArgumentException("Invalid data value, must between 0 and 1.");
                //}
                percent = percent > 1
                    ? 1
                    : percent < 0
                    ? 0
                    : percent;
                return new SolidColorBrush(
                    MixColor(
                        percent,
                        new KeyValuePair<double, Color>(0, Colors.Red),
                        new KeyValuePair<double, Color>(0.5, Colors.Yellow),
                        new KeyValuePair<double, Color>(1, Colors.Green)
                        ));
            }
            throw new ArgumentException("Invalid data type, type of double is required.");
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException("No need to convert back.");
        }

        private Color MixColor(double value, params KeyValuePair<double, Color>[] colors)
        {
            double percent = value / (colors.Select(pair => pair.Key).Sum());

            //上限值
            var pair1 = colors.Single(
                col =>
                    col.Key - value == colors.Min(
                        pair =>
                        {
                            return pair.Key - value < 0 ? double.MaxValue : pair.Key - value;
                        }));
            //下限值
            var pair2 = colors.SingleOrDefault(
                col =>
                    pair1.Key - col.Key == colors.Min(
                        pair =>
                        {
                            return pair1.Key - pair.Key <= 0 ? double.MaxValue : pair1.Key - pair.Key;
                        }));
            if (pair2.Equals(default(KeyValuePair<double, Color>))) { pair2 = pair1; }
            var color1 = pair1.Value;
            var color2 = pair2.Value;
            var p = pair1.Key - pair2.Key == 0
                ? 0
                : (value - pair2.Key) / (pair1.Key - pair2.Key);

            return new Color()
            {
                A = System.Convert.ToByte(color1.A * p + color2.A * (1 - p)),
                R = System.Convert.ToByte(color1.R * p + color2.R * (1 - p)),
                G = System.Convert.ToByte(color1.G * p + color2.G * (1 - p)),
                B = System.Convert.ToByte(color1.B * p + color2.B * (1 - p))
            };
        }
    }
}
